package org.monitor.model;

import java.io.File;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.monitor.config.MonitorConfig;

public class MonitorStateManager {
	
	public static final String ANONYMOUS = "anonymous";
	
	public static final String TYPE_SERVER = "server";
	public static final String TYPE_APP = "app";

	private static Map<String, MonitorStateManager> managerMap = init();
	
	
	private String type;
	private Map<String, Map<String, Boolean>> serverMap;
	
	private MonitorStateManager(String type){
		this.type = type;
		serverMap = new ConcurrentHashMap<String, Map<String, Boolean>>();
	}
	
	/**
	 * 默认获取ma server端监控状态管理对象
	 * @return
	 */
	public static MonitorStateManager getServerInstance(){
		return getInstance(TYPE_SERVER);
	}
	

	/**
	 * 默认获取app端监控状态管理对象
	 * @return
	 */
	public static MonitorStateManager getAppInstance(){
		return getInstance(TYPE_APP);
	}
	
	/**
	 * 根据监控方式获取监控状态管理对象
	 * @param type
	 * @return
	 */
	public static MonitorStateManager getInstance(String type){
		return managerMap.get(type);
	}

	private static Map<String, MonitorStateManager> init() {
		Map<String, MonitorStateManager> managerMap = new ConcurrentHashMap<String, MonitorStateManager>();
		managerMap.put(TYPE_APP, new MonitorStateManager(TYPE_APP));
		managerMap.put(TYPE_SERVER, new MonitorStateManager(TYPE_SERVER));
		return managerMap;
	}
	
	public void start(String ip, String port, String monitor){
		String server = ip + "_" + port;
		Map<String, Boolean> monitorMap = serverMap.get(server);
		if(monitorMap == null){
			Lock lock = new ReentrantLock();
			lock.lock();
			try {
				monitorMap = serverMap.get(server);
				if(monitorMap == null){
					monitorMap = new ConcurrentHashMap<String, Boolean>();
					serverMap.put(server, monitorMap);
				}
			}catch(Exception e){
			}finally {
				lock.unlock();
			}
		}
		monitorMap.put(monitor, true);
	}
	
	public void stop(String ip, String port, String monitor){
		String server = ip + "_" + port;
		Map<String, Boolean> monitorMap = serverMap.get(server);
		if(monitorMap != null){
			monitorMap.put(monitor, false);
		}
	}
	
	public boolean hasMonitoring(String ip, String port, String monitor){
		boolean flag = false;
		String server = ip + "_" + port;
		Map<String, Boolean> monitorMap = serverMap.get(server);
		if(monitorMap != null){
			Boolean monitoring = monitorMap.get(monitor);
			flag = monitoring != null ? monitoring : false;
		}
		return flag;
	}
	
	public boolean hasMonitoring(String ip, String port){
		boolean flag = false;
		String server = ip + "_" + port;
		Map<String, Boolean> monitorMap = serverMap.get(server);
		if(monitorMap != null){
			for (Entry<String, Boolean> entry : monitorMap.entrySet()) {
				Boolean monitoring = entry.getValue();
				flag = monitoring != null ? monitoring : false;
				if(flag){
					return flag;
				}
			}
		}
		return flag;
	}
	
	/**
	 * 监控日志存储目录
	 * @return
	 */
	public StringBuilder getStoreDir(){
		StringBuilder sb = new StringBuilder(MonitorConfig.get().getStoreDir());
		sb.append(File.separator).append(getType());
		return sb;
	}
	
	public StringBuilder getServerDir(String ip, String port){
		StringBuilder sb = getStoreDir();
		sb.append(File.separator).append(ip).append("_").append(port).append(File.separator);
		return sb;
	}
	
	public StringBuilder getMonitorDir(String ip, String port, String monitor){
		StringBuilder sb = getServerDir(ip, port);
		
		if(monitor == null || "".equals(monitor.trim())){
			monitor = ANONYMOUS;
		}
		
		sb.append(monitor).append(File.separator);
		return sb;
	}

	public String getType() {
		return type;
	}
}
